home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 12 / BBS in a box XII-2.iso / Files II / Prog / D-G / Extension Shell 1.3.sit / Extension Shell 1.3 ƒ / Extension Shell 1.3 (Source) / InstallCode.c / InstallCode.c
Encoding:
Text File  |  1994-04-06  |  12.0 KB  |  498 lines  |  [TEXT/R*ch]

  1. /*    NAME:
  2.         InstallCode.c
  3.  
  4.     WRITTEN BY:
  5.         Dair Grant
  6.                 
  7.     DESCRIPTION:
  8.         Routines for installing the various code resources Extension Shell supports.
  9.  
  10.     ___________________________________________________________________________
  11.  
  12.     VERSION HISTORY:
  13.         (Jan 1994, dg)
  14.             •    Added low-memory filter support.
  15.  
  16.         (Jan 1994, dg)
  17.             •    First publicly distributed version.
  18.  
  19.         (Mar 1994, dg)
  20.             •    Added support for code blocks.
  21.             
  22.             
  23.     ___________________________________________________________________________
  24. */
  25. //=============================================================================
  26. //        Include files                                                                     
  27. //-----------------------------------------------------------------------------
  28. #include <GestaltEqu.h>
  29. #include <Shutdown.h>
  30. #include "ParamBlock.h"
  31. #include "InstallCode.h"
  32. #include "ExtensionShell.h"
  33. #include "AddrsTable.h"
  34.  
  35.  
  36.  
  37.  
  38.  
  39. //=============================================================================
  40. //        Private function prototypes                                                                     
  41. //-----------------------------------------------------------------------------
  42. OSErr    InstallTrapPatch(short i, Ptr theCode);
  43. OSErr    InstallGestaltSelector(short i, Ptr theCode);
  44. OSErr    InstallShutdownTask(short i, Ptr theCode);
  45. OSErr    InstallVBLTask(short i, Ptr theCode);
  46. OSErr    InstallLowMemFilter(short i, Ptr theCode);
  47. OSErr    InstallCodeBlock(short i, Ptr theCode);
  48. OSErr    InstallTimeManagerTask(short i, Ptr theCode);
  49.  
  50.  
  51.  
  52.  
  53.  
  54. //=============================================================================
  55. //        Global variables                                                                 
  56. //-----------------------------------------------------------------------------
  57. extern ESParamBlock        gTheParamBlock;
  58. extern AddressTable        *gTheAddressTable;
  59.  
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68.  
  69. //=============================================================================
  70. //        InstallCode : Install a code resource depending on its type.                                                                 
  71. //-----------------------------------------------------------------------------
  72. //        Note :    We get the index of something in gTheParamBlock.TheCodeResources
  73. //                and case out on its type to do the installation. Both ourselves
  74. //                and the actual install routines are only expected to return any
  75. //                error code that arises. If an error does occur, our caller
  76. //                looks after filling in the other error details in gTheParamBlock.
  77. //-----------------------------------------------------------------------------
  78. OSErr InstallCode(short i)
  79. {    Handle        theHnd;
  80.     OSErr        theErr;
  81.     Ptr            theCode;
  82.     int            theType;
  83.     
  84.     
  85.  
  86.  
  87.     // Get the code resource in question, and abort if it wasn't there.
  88.     theHnd = GetResource(gTheParamBlock.theCodeResources[i].resType,
  89.                          gTheParamBlock.theCodeResources[i].resID);
  90.     if (theHnd == nil)
  91.         return(resNotFound);
  92.  
  93.  
  94.     
  95.     // Unlock, move high, and lock the resource. Then detach it so
  96.     // it stays around after Extension Shell is gone.
  97.     HUnlock(theHnd);
  98.     HLockHi(theHnd);
  99.     DetachResource(theHnd);
  100.  
  101.  
  102.  
  103.     // Get a clean address from the handle
  104.     theCode = (Ptr) StripAddress(*theHnd);
  105.  
  106.  
  107.  
  108.     // Now case out on the type of the code, and call the install routine
  109.     switch(gTheParamBlock.theCodeResources[i].codeType) {
  110.         case kTrapPatchType:
  111.              theErr = InstallTrapPatch(i, theCode);
  112.              break;
  113.              
  114.         case kGestaltSelectorType:
  115.              theErr = InstallGestaltSelector(i, theCode);
  116.              break;
  117.              
  118.         case kShutdownTaskType:
  119.              theErr = InstallShutdownTask(i, theCode);
  120.              break;
  121.              
  122.         case kVBLTaskType:
  123.              theErr = InstallVBLTask(i, theCode);
  124.              break;
  125.         
  126.         case kLowMemFilterType:
  127.              theErr = InstallLowMemFilter(i, theCode);
  128.              break;
  129.         
  130.         case kCodeBlockType:
  131.              theErr = InstallCodeBlock(i, theCode);
  132.              break;
  133.         
  134.         case kTimeManagerTaskType:
  135.              theErr = InstallTimeManagerTask(i, theCode);
  136.              break;
  137.         
  138.         default:
  139.              theErr = noErr;
  140.     }
  141.  
  142.     
  143.     
  144.     return(theErr);
  145.  
  146.  
  147.  
  148.  
  149.  
  150.  
  151.  
  152.  
  153.  
  154.  
  155. //=============================================================================
  156. //        InstallAddressTable : Install an address table for the INIT.
  157. //-----------------------------------------------------------------------------
  158. //        Note :    We install the Gestalt selector, get a hold of the address
  159. //                table and leave the address of the table in the global
  160. //                gTheAddressTable.
  161. //-----------------------------------------------------------------------------
  162. void InstallAddressTable(void)
  163. {    Handle            theHnd;
  164.     OSErr            theErr;
  165.     
  166.  
  167.  
  168.  
  169.     // Load the AddressTable Gestalt selector, and install it with NewGestalt.
  170.     // If we can't get it, we die.
  171.     theHnd = GetResource(kAddrsTableCodeType, kAddrsTableCodeID);
  172.     if (theHnd == nil)
  173.         DebugStr("\pExtension Shell - couldn't find AddressTable CODE resource");
  174.     
  175.         
  176.     
  177.     // We have it, so prepare the code by detaching it and locking it high
  178.     HUnlock(theHnd);
  179.     HLockHi(theHnd);
  180.     DetachResource(theHnd);
  181.     
  182.     
  183.     
  184.     // Install it as a Gestalt selector
  185.     theErr = NewGestalt(gTheParamBlock.addressTableSelector, (ProcPtr) *theHnd);
  186.     if (theErr != noErr)
  187.         DebugStr("\pExtension Shell - couldn't install AddressTable");
  188.         
  189.  
  190.  
  191.     // Call the new routine to get the address of the address table
  192.     theErr = Gestalt(gTheParamBlock.addressTableSelector, &gTheAddressTable);
  193.     if (theErr != noErr)
  194.         DebugStr("\pExtension Shell - couldn't call AddressTable");
  195. }
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202.  
  203.  
  204.  
  205.  
  206. //=============================================================================
  207. //        InstallTrapPatch : Install a trap patch.                                                         
  208. //-----------------------------------------------------------------------------
  209. //        Note :    Given a trap number and a pointer to the new routine, we save
  210. //                the original entry in the dispatch table and insert ours.
  211. //
  212. //                We assume that the trap *is* implemented.
  213. //-----------------------------------------------------------------------------
  214. OSErr InstallTrapPatch(short i, Ptr theCode)
  215. {    OSErr        theErr;
  216.     int            trapNum;
  217.     TrapType    tType;
  218.     ProcPtr        oldCodeAddress;
  219.     
  220.     
  221.     
  222.     
  223.      // Copy the relevent details into local variables for speed
  224.      trapNum            = gTheParamBlock.theCodeResources[i].theCodeThing.theTrapPatch.trapNum;
  225.  
  226.  
  227.  
  228.      // Get the type of the trap
  229.     tType = GetTrapType(trapNum);
  230.     
  231.     
  232.     
  233.     // Replace the old value in the dispatch table with the new value.
  234.     oldCodeAddress = (ProcPtr) StripAddress((Ptr) NGetTrapAddress(trapNum, tType));
  235.     NSetTrapAddress((long) theCode, trapNum, tType);
  236.     theErr = noErr;
  237.     
  238.     
  239.     
  240.     // If there wasn't a problem, fill in the entry in the address table
  241.     // and save the address of the new code.
  242.     if (theErr == noErr)
  243.         {
  244.         gTheAddressTable->theTable[i]                    = oldCodeAddress;
  245.         gTheParamBlock.theCodeResources[i].theAddress    = theCode;
  246.         }
  247.     
  248.     
  249.     
  250.     // If there was a problem, return it
  251.     return(theErr);    
  252. }
  253.  
  254.  
  255.  
  256.  
  257.  
  258.  
  259.  
  260.  
  261.  
  262.  
  263. //=============================================================================
  264. //        InstallGestaltSelector : Install a Gestalt Selector.                                                         
  265. //-----------------------------------------------------------------------------
  266. OSErr InstallGestaltSelector(short i, Ptr theCode)
  267. {    OSErr                theErr;
  268.     AGestaltSelector    *theGestaltInfo;
  269.  
  270.  
  271.  
  272.  
  273.     // Get a pointer to the information to save on dereferences
  274.     theGestaltInfo = &gTheParamBlock.theCodeResources[i].theCodeThing.theGestaltSelector;
  275.     
  276.     
  277.     
  278.     // Try and install the routine
  279.     theErr = NewGestalt(theGestaltInfo->theSelector, (ProcPtr) theCode);
  280.     
  281.     
  282.     
  283.     // If the selector exists, replace it if we're allowed to, and save
  284.     // the address of the old routine in the address table
  285.     if (theErr == gestaltDupSelectorErr && theGestaltInfo->overwriteExistingSelector)
  286.         theErr = ReplaceGestalt(theGestaltInfo->theSelector,
  287.                                 theCode,
  288.                                 &gTheAddressTable->theTable[i]);
  289.     
  290.     
  291.     
  292.     // If there wasn't a problem, save the address of the new code. The address
  293.     // table is only used if we need to get access to the old Gestalt routine.
  294.     if (theErr == noErr)
  295.         gTheParamBlock.theCodeResources[i].theAddress = theCode;
  296.         
  297.         
  298.     
  299.     // If there was a problem, return it
  300.     return(theErr);
  301. }
  302.  
  303.  
  304.  
  305.  
  306.  
  307.  
  308.  
  309.  
  310.  
  311.  
  312. //=============================================================================
  313. //        InstallShutdownTask : Install a Shutdown Task.                                                         
  314. //-----------------------------------------------------------------------------
  315. OSErr InstallShutdownTask(short i, Ptr theCode)
  316. {    OSErr    theErr;
  317.  
  318.  
  319.  
  320.  
  321.     // Install the task with its flags. We assume no errors can occur.
  322.     ShutDwnInstall((ShutDwnProcPtr) theCode,
  323.                    gTheParamBlock.theCodeResources[i].theCodeThing.theShutdownTask.theFlags);
  324.     theErr = noErr;    
  325.     
  326.     
  327.     
  328.     // Save the address in gTheParamBlock. We don't use the address table at all.
  329.     if (theErr == noErr)
  330.         gTheParamBlock.theCodeResources[i].theAddress = theCode;
  331.  
  332.  
  333.  
  334.     // If there was a problem, return it
  335.     return(theErr);
  336. }
  337.  
  338.  
  339.  
  340.  
  341.  
  342.  
  343.  
  344.  
  345.  
  346.  
  347. //=============================================================================
  348. //        InstallVBLTask : Install a VBL task.                                                         
  349. //-----------------------------------------------------------------------------
  350. OSErr InstallVBLTask(short i, Ptr theCode)
  351. {    VBLTask         *theVblPtr;
  352.     OSErr            theErr;
  353.     
  354.     
  355.     
  356.     
  357.     // Allocate a little block of memory in the System Heap for the task information
  358.     theVblPtr = (VBLTask*) NewPtrSys(sizeof(VBLTask));
  359.     
  360.     
  361.     
  362.     // Fill in the fields, and install it as a VBL task
  363.     theVblPtr->qType    = vType;
  364.     theVblPtr->vblAddr  = (VBLProcPtr) theCode;
  365.     theVblPtr->vblCount = gTheParamBlock.theCodeResources[i].theCodeThing.theVBLTask.vblCount;
  366.     theVblPtr->vblPhase = gTheParamBlock.theCodeResources[i].theCodeThing.theVBLTask.vblPhase;
  367.     theErr = VInstall(theVblPtr);
  368.     
  369.     
  370.     
  371.     // Save the address of the VBLTask structure in the address table and the param block
  372.     if (theErr == noErr)
  373.         {
  374.         gTheAddressTable->theTable[i]                    = (ProcPtr) theVblPtr;
  375.         gTheParamBlock.theCodeResources[i].theAddress    = (Ptr) theVblPtr;
  376.         }
  377.     
  378.     
  379.     // If there was a problem, return it
  380.     return(theErr);
  381. }
  382.  
  383.  
  384.  
  385.  
  386.  
  387.  
  388.  
  389.  
  390.  
  391.  
  392. //=============================================================================
  393. //        InstallLowMemFilter : Install a low-memory filter.                                                         
  394. //-----------------------------------------------------------------------------
  395. OSErr InstallLowMemFilter(short i, Ptr theCode)
  396. {    ProcPtr        theEntryPoint;
  397.     
  398.  
  399.  
  400.     
  401.     // Get the address of the filter chain.
  402.     theEntryPoint = (ProcPtr) gTheParamBlock.theCodeResources[i].theCodeThing.theLowMemFilter.theEntryPoint;
  403.     
  404.     
  405.     
  406.     // Save the address currently at the front of the chain in the address table
  407.     // and save ourselves in the param block.
  408.     gTheAddressTable->theTable[i]                    = (ProcPtr) *((void **) theEntryPoint);
  409.     gTheParamBlock.theCodeResources[i].theAddress    = theCode;
  410.     
  411.     
  412.     
  413.     // Insert ourselves into the front of the chain
  414.     *((long *) theEntryPoint) = (long) theCode;
  415.  
  416.  
  417.  
  418.     // If there was a problem, return it
  419.     return(noErr);
  420. }
  421.  
  422.  
  423.  
  424.  
  425.  
  426.  
  427.  
  428.  
  429.  
  430.  
  431. //=============================================================================
  432. //        InstallCodeBlock : Install a block of code.                                                         
  433. //-----------------------------------------------------------------------------
  434. OSErr InstallCodeBlock(short i, Ptr theCode)
  435. {    ProcPtr        theEntryPoint;
  436.     
  437.     
  438.  
  439.     
  440.     // Set the reserved field to some value
  441.     gTheParamBlock.theCodeResources[i].theCodeThing.theCodeBlock.reserved = 0x0000;
  442.     
  443.     
  444.     
  445.     // Save the address of the code block in the address table and the param block
  446.     gTheAddressTable->theTable[i]                    = (ProcPtr) theCode;
  447.     gTheParamBlock.theCodeResources[i].theAddress    = theCode;
  448.  
  449.  
  450.  
  451.     // If there was a problem, return it
  452.     return(noErr);
  453. }
  454.  
  455.  
  456.  
  457.  
  458.  
  459.  
  460.  
  461.  
  462.  
  463.  
  464. //=============================================================================
  465. //        InstallTimeManagerTask : Install a Time Manager task.                                                         
  466. //-----------------------------------------------------------------------------
  467. OSErr InstallTimeManagerTask(short i, Ptr theCode)
  468. {    TMTask             *theTaskPtr;
  469.  
  470.  
  471.  
  472.  
  473.     // Allocate a little block of memory in the System Heap for the task information
  474.     theTaskPtr = (TMTask*) NewPtrSys(sizeof(TMTask));
  475.     
  476.     
  477.     
  478.     // Fill in the fields, and install it as an Time Manager task. We don't install
  479.     // it as with InsXTime because we probably won't need that accurate timing.
  480.     theTaskPtr->tmAddr    = (ProcPtr) theCode;
  481.     theTaskPtr->tmCount    = 0;
  482.     InsTime(theTaskPtr);
  483.     PrimeTime(theTaskPtr,
  484.                 gTheParamBlock.theCodeResources[i].theCodeThing.theTimeManagerTask.theDelay);
  485.     
  486.     
  487.     
  488.     // Save the address of the TMTask structure in the address table and the param block
  489.     gTheAddressTable->theTable[i]                    = (ProcPtr) theTaskPtr;
  490.     gTheParamBlock.theCodeResources[i].theAddress    = (Ptr) theTaskPtr;
  491.     
  492.     
  493.     
  494.     // Return no errors
  495.     return(noErr);
  496. }
  497.